<?php
/**
 * Created by PhpStorm.
 * User: 丶晓
 * Date: 2017/9/25
 * Time: 9:46
 */

namespace app\api\controller;

use think\Db;
use think\Config;
use think\Request;
use think\Validate;
use app\api\common\Tools;
use app\api\model\DataModel;
use app\api\service\PayService;
use app\api\service\DataService;
use app\api\model\MiniappsModel;

class Wechatpay extends PayService
{

    // +++++++++++++++++++++++++++++++++++++++++++++++++++
    // | 用户购买模板 $_GET template_id and $_GET uid @xiao
    // | api: [ https://api.suyongw.com/wechatPay/template ]
    // | method: GET
    // | parm: {
    // |     uid : 平台用户ID
    // |     template_id : 微信小程序模板ID
    // | }
    // | 默认返回 二维码 Src
    // +++++++++++++++++++++++++++++++++++++++++++++++++++
    public function template()
    {
        $Tools = new Tools();
        if (!isset($_GET['template_id']) or empty($_GET['uid'])) {
            return $Tools->error('Request fail!');
        }
        $template_id = $_GET['template_id']; // 商品参数整理
        $uid = $_GET['uid'];  // 商品参数整理

        if ((empty($template_id) and $template_id != 0) or empty($uid)) {
            return $Tools->error('Request lost!'); // 参数不全
        }

        /*  检测用户是否存在 */
        if (Db::table('wyz_userinfo')->where('id', 'eq', $uid)->count() != 1) {
            return $Tools->error('Undefind user id');
        }

        /* 获取购买的模板详情 */
        $DataService = new DataService();
        $temp = $DataService->Template($template_id);
        if (!$temp) {
            return $Tools->error('Undefind template id');
        }

        /* 是否已经购买了该模板 */
        if ($DataService->isBuyTemplate($uid, $template_id)) {
            return $Tools->error('You got this template!');
        }

        /* 免费模板购买 */
        if ($temp['price'] <= 0) {
            $Model = new MiniappsModel();
            if ($Model->addInfo('zeroPriceTemplate', ['uid' => $uid, 'template_id' => $template_id])) {
                return $Tools->success('Buy success!');
            }
            return $Tools->error('Buy fail!db error 302');
        }

        // 订单详情
        $parms = [
            'price' => $temp['price'],
            'source' => '【速用科技】小程序模板<' . $temp['source'] . '> version:' . $temp['version'],
            'describe' => '适用于:' . $temp['temp_use'] . '等领域，主要组件有：' . $temp['main_ele']
        ];
        $orderId = $this->addInfo('int_buyTemplate', ['template_id' => $template_id, 'uid' => $uid]);
        if ($orderId) {
            $parms['out_trade_no'] = 'TPL_' . Config::get('wechatPay.order_no');  // 订单号码生成
            $RES = $this->signPay('wechat', 'scan', $parms);
            if ($RES and $this->payProcess('ready_buy_template_wechat', ['out_trade_no' => $parms['out_trade_no'], 'uid' => $uid, 'order_id' => $orderId])) { // 写订单入库
                return $Tools->success('Request success!', ['OrderId' => $orderId, 'link' => 'http://qr.topscan.com/api.php?text=' . $RES . '&w=500']);
            }
        }
        return $Tools->error('Pay fail!');
    }

    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // | 用户充值速用币 $_GET price and $_GET uid @xiao
    // | api: [ https://api.suyongw.com/wechatPay/recharge ]
    // | method: GET
    // | parm: {
    // |     uid : 平台用户ID
    // |     price : 充值数量 必须为整数 integer
    // |     isSrc : 是否返回 二维码图片地址 & 否则为 支付宝API下单链接
    // | }
    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    public function recharge()
    {
        $Tools = new Tools();
        if (!isset($_GET['price']) or !isset($_GET['uid'])) {
            return $Tools->error('Request fail!');
        }
        $price = $_GET['price']; // 价格
        $uid = $_GET['uid'];  // 商品参数整理

        if (empty($price) or empty($uid)) {
            return $Tools->error('Request lost!'); // 参数不全
        }

        /*  检测用户是否存在 */
        if (Db::table('wyz_userinfo')->where('id', 'eq', $uid)->count() != 1) {
            return $Tools->error('Undefind user id');
        }

        /*
         *        此处省略返利业务逻辑
         *        此处省略返利业务逻辑
         *        此处省略返利业务逻辑
         *        此处省略返利业务逻辑
         *        此处省略返利业务逻辑
         */

        $validate = new Validate([
            'price' => 'require|number|integer',
        ]);
        if (!$validate->check(['price' => $price])) {
            return $Tools->error($validate->getError());
        }


        // 订单详情
        $parms = [
            'price' => $price,
            'source' => '【速用科技】充值速用币 - 平台充值',
            'describe' => '速用平台专用虚拟币，可用于购买平台内相关业务内容及分发虚拟币等用途 - 详情了解 www.suyongw.com SuYong Co. &copy;2016-' . date('Y'),
        ];
        $orderId = $this->addInfo('int_recharge', ['uid' => $uid, 'price' => $price]);
        if ($orderId) {
            $parms['out_trade_no'] = 'TPL_' . Config::get('wechatPay.order_no');  // 订单号码生成
            $RES = $this->signPay('wechat', 'scan', $parms);
            if ($RES and $this->payProcess('ready_pay_recharge_wechat', ['out_trade_no' => $parms['out_trade_no'], 'uid' => $uid, 'order_id' => $orderId])) { // 写订单入库
                return $Tools->success('Request success!', ['OrderId' => $orderId, 'link' => 'http://qr.topscan.com/api.php?text=' . $RES . '&w=500']);
            }
        }
        return $Tools->error('Pay fail!');
    }

    // ++++++++++++++++++++++++++++++
    // | 小程序支付请求接口  @xiao
    // | api: [ https://api.suyongw.com/wechatPay/miniAppPay ]
    // | method: POST
    // | parm: {
    // |     miniapp_id : miniapps 表主键ID
    // |     out_trade_no : 订单号
    // |     total_fee : 订单金额，**单位：元 0.01 最低**
    // |     body : 订单描述
    // |     openid : 支付人的 openID
    // |  }
    // ++++++++++++++++++++++++++++++
    public function miniAppPay(Request $request)
    {
        $miniapp_id = $request->post('miniapps_id');
        $out_trade_no = $request->post('out_trade_no');
        $total_fee = $request->post('total_fee');
        $body = $request->post('body');
        $openid = $request->post('openid');
        $Tools = new Tools();
        if (Db::table('wyz_miniapps')->where('id', 'eq', $miniapp_id)->count() != 1) {
            return $Tools->error('Undefind miniapp id');
        }

        $validate = new Validate([
            'miniapp_id' => 'require',
            'total_fee' => 'require|number',
            'out_trade_no' => 'require',
            'body' => 'require',
            'openid' => 'require',
        ]);

        if (!$validate->check([
            'miniapp_id' => $miniapp_id,
            'out_trade_no' => $out_trade_no,
            'total_fee' => $total_fee,
            'body' => $body,
            'openid' => $openid
        ])) {
            return $Tools->error($validate->getError());
        }
        $DataService = new DataService();
        $parms = $DataService->getMiniappsPayDatas('getAllMchPayFile', ['miniID' => $miniapp_id]);
        if (empty($parms)) {
            return $Tools->error('Undefind Mch Data!');
        }
        $parms['out_trade_no'] = $out_trade_no;
        $parms['total_fee'] = $total_fee;
        $parms['body'] = $body;
        $parms['openid'] = $openid;
        $RES = $this->signPay('wechat', 'miniapp', $parms);
        if ($RES and $this->payProcess('create_miniapp_order', ['out_trade_no' => $parms['out_trade_no']])) { // 写订单入库
            return $Tools->success('Request success!', $RES);
        }
        return $Tools->error('Request fail!');
    }

    // ++++++++++++++++++++++++++++++
    // |  扫码支付成功时 异步回调方法
    // ++++++++++++++++++++++++++++++
    public function redirect_url()
    {
        $postStr = file_get_contents("php://input");
        if (!$this->wechatPayReturn($postStr, 'scan')) {
            echo 'failed';
            exit();
        }
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        $orderInfo = json_encode([
            'bank_type' => $postObj->bank_type,
            'cash_fee' => $postObj->cash_fee,
            'fee_type' => $postObj->fee_type,
            'time_end' => $postObj->time_end,
        ], JSON_UNESCAPED_UNICODE);
        $parm = [
            'order_info' => $orderInfo,
            'out_trade_no' => $postObj->out_trade_no,
            'sign' => $postObj->sign,
            'transaction_id' => $postObj->transaction_id,
            'trade_type' => $postObj->trade_type,
            'open_id' => $postObj->openid,
            'is_subscribe' => $postObj->is_subscribe == 'Y' ? 1 : 0,
            'is_sign' => $postObj->result_code == 'SUCCESS' and $postObj->result_code == 'SUCCESS' ? 1 : 0,
            'price' => $postObj->total_fee * 100  // 单位：分
        ];
        if (!$this->changeInfo('success_wechatPay_order', $parm)) {
            echo 'failed';  // 待写入支付失败日志
            exit();
        }
        echo 'success';
        exit();
    }

    // ++++++++++++++++++++++++++++++
    // |  小程序支付成功时 异步回调方法
    // ++++++++++++++++++++++++++++++
    public function miniapp_redirect_url()
    {
        $postStr = file_get_contents("php://input");
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        if(empty($postObj)){
            echo 'failed';
            exit();
        }
        $parm = [
            'bank_type' => json_decode(json_encode($postObj->bank_type),true)[0],
            'cash_fee' => $postObj->cash_fee,
            'fee_type' => json_decode(json_encode($postObj->fee_type),true)[0],
            'time_end' => json_decode(json_encode($postObj->time_end),true)[0],
            'out_trade_no' => json_decode(json_encode($postObj->out_trade_no),true)[0],
            'sign' => json_decode(json_encode($postObj->sign),true)[0],
            'transaction_id' => json_decode(json_encode($postObj->transaction_id),true)[0],
            'trade_type' => json_decode(json_encode($postObj->trade_type),true)[0],
            'open_id' => json_decode(json_encode($postObj->openid),true)[0],
            'is_subscribe' => $postObj->is_subscribe == 'Y' ? 1 : 0,
            'is_sign' => $postObj->result_code == 'SUCCESS' and $postObj->result_code == 'SUCCESS' ? 1 : 0,
            'price' => $postObj->total_fee * 100  // 单位：分
        ];
        if ($this->changeInfo('success_miniapps_pay', $parm)) {
            echo 'success';
            exit();
        }
        echo 'failed';  // 待写入支付失败日志
        exit();
    }

    // ++++++++++++++++++++++++++++++
    // | 设置小程序微信支付接口数据 @Xiao
    // | POST  miniapps_id  mch_id  secret  cert 文件 key 文件
    // ++++++++++++++++++++++++++++++
    public function uploadSetPayFile(Request $request)
    {
        $miniapps_id = $request->post('miniapps_id'); // 小程序ID
        $mch_id = $request->post('mch_id');           // 商户号
        $secret = $request->post('secret');           // 商户秘钥
        $cert = $request->file('cert');              // 商户证书
        $key = $request->file('key');                // 商户私钥

        $DataModel = new DataModel();
        $appid = $DataModel->selectInfo('appid_miniID', ['id' => $miniapps_id]);

        $Tools = new Tools();

        /* 验证上传数据 */
        $validate = new Validate([
            'appid' => 'require',
            'mch_id' => 'require',
            'secret' => 'require',
            'cert' => 'require',
            'key' => 'require',
        ]);
        $data = [
            'appid' => $appid,
            'mch_id' => $mch_id,
            'secret' => $secret,
            'cert' => $cert,
            'key' => $key,
        ];
        if (!$validate->check($data)) {
            return $Tools->error($validate->getError());
        }

        /* 上传文件证书到本地保存 PS：文件证书及私钥 在订单退款及查询评价时使用 */
        $cert_info = $cert->validate(['ext' => 'pem'])->rule('uniqid')
            ->move(ROOT_PATH . 'thinkphp' . DS . 'wechatPayFile' . DS . 'mch_file' . DS . 'appid_' . $appid . DS . 'CERT' . DS);
        if ($cert_info) {
            $cert = 'thinkphp' . DS . 'wechatPayFile' . DS . 'mch_file' . DS . 'appid_' . $appid . DS . 'CERT' . DS . $cert_info->getSaveName();
        } else {
            return $Tools->error('cert must be .pem file');
        }
        $key_info = $key->validate(['ext' => 'pem'])->rule('uniqid')
            ->move(ROOT_PATH . 'thinkphp' . DS . 'wechatPayFile' . DS . 'mch_file' . DS . 'appid_' . $appid . DS . 'KEY' . DS);
        if ($key_info) {
            $key = 'thinkphp' . DS . 'wechatPayFile' . DS . 'mch_file' . DS . 'appid_' . $appid . DS . 'KEY' . DS . $key_info->getSaveName();
        } else {
            return $Tools->error('key must be .pem file');
        }

        $data['cert'] = $cert;
        $data['key'] = $key;

        /* 保存入库商户小程序支付资料 */
        $RES = $this->saveMchPayFile($data);
        if ($RES) {
            return $Tools->success('set file success!');
        }
        return $Tools->error('vaildate file fail!');
    }

}